<template>
  <div class="w-full h-full flex flex-col ev-table">
    <div class="w-full flex justify-between p10 mb-10 bg-#fff" v-if="$slots?.searchSlot">
      <slot name="searchSlot"></slot>
    </div>
    <div v-if="hasToolbar" class="w-full pl10 pr10 bg-#fff">
      <vxe-toolbar ref="toolbarRef" v-bind="props.evToolsOptions">
        <template #buttons>
          <slot name="buttonsSlot"></slot>
        </template>
        <template #tools>
          <n-space>
            <slot name="toolsSlot"></slot>
            <n-button circle @click="refreshTableList">
              <template #icon>
                <IconRefresh></IconRefresh>
              </template>
            </n-button>
          </n-space>
        </template>
      </vxe-toolbar>
    </div>
    <div
      :class="!hasToolbar ? 'pt-10px' : ''"
      class="flex-1 overflow-hidden pl10 pr10 pb10 bg-white"
    >
      <vxe-table
        ref="tableRef"
        class="w-full"
        align="center"
        :data="tableData"
        :loading="loading"
        v-bind="defaultEvTableOptions"
      >
        <slot name="tableSlot"></slot>
      </vxe-table>
    </div>
    <div
      v-if="hasPager"
      style="background: #ffffff;"
      class="w-full pb-10 pl-10 pr-10 flex items-center justify-end"
    >
      <n-pagination
        v-model:page="defaultParams.pageIndex"
        v-model:page-size="defaultParams.pageSize"
        :item-count="total"
        :on-update-page="getTableList"
        :on-update-page-size="getTableList"
        size="medium"
        :page-sizes="[10, 20, 50, 100]"
        show-quick-jumper
        show-size-picker
      >
        <template #prefix="{ itemCount }"> 共 {{ itemCount }} 条 </template>
      </n-pagination>
    </div>
  </div>
</template>

<script setup name="EvTable">
import { nextTick, onMounted, ref, shallowRef, defineSlots } from 'vue';
import { IconRefresh } from '@/components/app-icons/index.js';
import cloneDeep from 'lodash-es/cloneDeep.js';

const props = defineProps({
  // 定义接受table属性
  evTableOptions: {
    type: Object,
    default: null,
  },
  // 定义接受toolbar属性
  evToolsOptions: {
    type: [Object],
    default: () => ({
      custom: { isFooter: false, immediate: true },
    }),
  },
  // 表格请求数据的方法 要求返回一个Promise
  getTableDataFn: {
    type: Function,
    default: null,
  },
  // 表格请求数据时的参数
  getTableDataParams: {
    type: Object,
    default: null,
  },
  // 是否包含分页
  hasPager: {
    type: Boolean,
    default: false,
  },
  // 是否包含顶部工具栏
  hasToolbar: {
    type: Boolean,
    default: true,
  },
  // 是否手动加载
  lazyLoad: {
    type: Boolean,
    default: false,
  },
  // 树结构是否默认展开全部
  treeExpandAll: {
    type: Boolean,
    default: false,
  },
});

// 默认属性 (详见vxe官网)
const defaultEvTableOptions = ref({
  border: true,
  height: 'auto',
  autoResize: true,
  columnConfig: {
    resizable: true,
  },
  rowConfig: {
    isHover: true,
  },
});
if (props.evTableOptions) Object.assign(defaultEvTableOptions.value, props.evTableOptions);
const loading = shallowRef(false);
const toolbarRef = shallowRef(null);
const tableRef = shallowRef(null);
const slots = defineSlots();
// 将表格和工具栏进行关联
onMounted(() => {
  const $table = tableRef.value;
  const $toolbar = toolbarRef.value;
  $table && $toolbar && $table.connect($toolbar);
});

// 含有分页的表格分页数据
const defaultParams = ref({
  pageIndex: 1,
  pageSize: 10,
});
const tableData = ref([]);
const total = ref(0);
// 获取表格数据方法
const getTableList = async () => {
  tableData.value = [];
  total.value = 0;
  if (props.getTableDataFn) {
    const params = props.hasPager
      ? Object.assign(cloneDeep(defaultParams.value), props.getTableDataParams)
      : cloneDeep(props.getTableDataParams);
    loading.value = true;
    try {
      const res = await props.getTableDataFn(params);
      tableData.value = res.data;
      total.value = res.total;
      // 如果树级需要默认展开全部
      if (props.treeExpandAll) await nextTick(() => tableRef.value.setAllTreeExpand(true));
    } finally {
      loading.value = false;
    }
  }
};
const refreshTableList = () => {
  defaultParams.value.pageIndex = 1;
  getTableList();
};
onMounted(() => {
  !props.lazyLoad && getTableList();
});

defineExpose({
  tableRef,
  tableData,
  getTableList,
  refreshTableList,
});
</script>
<style lang="scss">
.ev-table {
  .vxe-custom--header {
    display: none;
  }
  .vxe-table--body,
  .vxe-table--header {
    width: 100% !important;
  }
}
</style>
<style scoped lang="scss"></style>
